home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / glibc108.gz / glibc108 / glibc-1.08.1 / sunrpc / rpc_parse.c < prev    next >
C/C++ Source or Header  |  1994-02-06  |  9KB  |  420 lines

  1. /* @(#)rpc_parse.c    2.1 88/08/01 4.0 RPCSRC */
  2. /*
  3.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  4.  * unrestricted use provided that this legend is included on all tape
  5.  * media and as a part of the software program in whole or part.  Users
  6.  * may copy or modify Sun RPC without charge, but are not authorized
  7.  * to license or distribute it to anyone else except as part of a product or
  8.  * program developed by the user.
  9.  * 
  10.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  11.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  12.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  13.  * 
  14.  * Sun RPC is provided with no support and without any obligation on the
  15.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  16.  * modification or enhancement.
  17.  * 
  18.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  19.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  20.  * OR ANY PART THEREOF.
  21.  * 
  22.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  23.  * or profits or other special, indirect and consequential damages, even if
  24.  * Sun has been advised of the possibility of such damages.
  25.  * 
  26.  * Sun Microsystems, Inc.
  27.  * 2550 Garcia Avenue
  28.  * Mountain View, California  94043
  29.  */
  30. #ifndef lint
  31. static char sccsid[] = "@(#)rpc_parse.c 1.4 87/04/28 (C) 1987 SMI";
  32. #endif
  33.  
  34. /*
  35.  * rpc_parse.c, Parser for the RPC protocol compiler 
  36.  * Copyright (C) 1987 Sun Microsystems, Inc.
  37.  */
  38. #include <stdio.h>
  39. #include "rpc_util.h"
  40. #include "rpc_scan.h"
  41. #include "rpc_parse.h"
  42.  
  43. /*
  44.  * return the next definition you see
  45.  */
  46. definition *
  47. get_definition()
  48. {
  49.     definition *defp;
  50.     token tok;
  51.  
  52.     defp = ALLOC(definition);
  53.     get_token(&tok);
  54.     switch (tok.kind) {
  55.     case TOK_STRUCT:
  56.         def_struct(defp);
  57.         break;
  58.     case TOK_UNION:
  59.         def_union(defp);
  60.         break;
  61.     case TOK_TYPEDEF:
  62.         def_typedef(defp);
  63.         break;
  64.     case TOK_ENUM:
  65.         def_enum(defp);
  66.         break;
  67.     case TOK_PROGRAM:
  68.         def_program(defp);
  69.         break;
  70.     case TOK_CONST:
  71.         def_const(defp);
  72.         break;
  73.     case TOK_EOF:
  74.         return (NULL);
  75.         break;
  76.     default:
  77.         error("definition keyword expected");
  78.     }
  79.     scan(TOK_SEMICOLON, &tok);
  80.     isdefined(defp);
  81.     return (defp);
  82. }
  83.  
  84. static
  85. isdefined(defp)
  86.     definition *defp;
  87. {
  88.     STOREVAL(&defined, defp);
  89. }
  90.  
  91.  
  92. static
  93. def_struct(defp)
  94.     definition *defp;
  95. {
  96.     token tok;
  97.     declaration dec;
  98.     decl_list *decls;
  99.     decl_list **tailp;
  100.  
  101.     defp->def_kind = DEF_STRUCT;
  102.  
  103.     scan(TOK_IDENT, &tok);
  104.     defp->def_name = tok.str;
  105.     scan(TOK_LBRACE, &tok);
  106.     tailp = &defp->def.st.decls;
  107.     do {
  108.         get_declaration(&dec, DEF_STRUCT);
  109.         decls = ALLOC(decl_list);
  110.         decls->decl = dec;
  111.         *tailp = decls;
  112.         tailp = &decls->next;
  113.         scan(TOK_SEMICOLON, &tok);
  114.         peek(&tok);
  115.     } while (tok.kind != TOK_RBRACE);
  116.     get_token(&tok);
  117.     *tailp = NULL;
  118. }
  119.  
  120. static
  121. def_program(defp)
  122.     definition *defp;
  123. {
  124.     token tok;
  125.     version_list *vlist;
  126.     version_list **vtailp;
  127.     proc_list *plist;
  128.     proc_list **ptailp;
  129.  
  130.     defp->def_kind = DEF_PROGRAM;
  131.     scan(TOK_IDENT, &tok);
  132.     defp->def_name = tok.str;
  133.     scan(TOK_LBRACE, &tok);
  134.     vtailp = &defp->def.pr.versions;
  135.     scan(TOK_VERSION, &tok);
  136.     do {
  137.         scan(TOK_IDENT, &tok);
  138.         vlist = ALLOC(version_list);
  139.         vlist->vers_name = tok.str;
  140.         scan(TOK_LBRACE, &tok);
  141.         ptailp = &vlist->procs;
  142.         do {
  143.             plist = ALLOC(proc_list);
  144.             get_type(&plist->res_prefix, &plist->res_type, DEF_PROGRAM);
  145.             if (streq(plist->res_type, "opaque")) {
  146.                 error("illegal result type");
  147.             }
  148.             scan(TOK_IDENT, &tok);
  149.             plist->proc_name = tok.str;
  150.             scan(TOK_LPAREN, &tok);
  151.             get_type(&plist->arg_prefix, &plist->arg_type, DEF_PROGRAM);
  152.             if (streq(plist->arg_type, "opaque")) {
  153.                 error("illegal argument type");
  154.             }
  155.             scan(TOK_RPAREN, &tok);
  156.             scan(TOK_EQUAL, &tok);
  157.             scan_num(&tok);
  158.             scan(TOK_SEMICOLON, &tok);
  159.             plist->proc_num = tok.str;
  160.             *ptailp = plist;
  161.             ptailp = &plist->next;
  162.             peek(&tok);
  163.         } while (tok.kind != TOK_RBRACE);
  164.         *vtailp = vlist;
  165.         vtailp = &vlist->next;
  166.         scan(TOK_RBRACE, &tok);
  167.         scan(TOK_EQUAL, &tok);
  168.         scan_num(&tok);
  169.         vlist->vers_num = tok.str;
  170.         scan(TOK_SEMICOLON, &tok);
  171.         scan2(TOK_VERSION, TOK_RBRACE, &tok);
  172.     } while (tok.kind == TOK_VERSION);
  173.     scan(TOK_EQUAL, &tok);
  174.     scan_num(&tok);
  175.     defp->def.pr.prog_num = tok.str;
  176.     *vtailp = NULL;
  177. }
  178.  
  179. static
  180. def_enum(defp)
  181.     definition *defp;
  182. {
  183.     token tok;
  184.     enumval_list *elist;
  185.     enumval_list **tailp;
  186.  
  187.     defp->def_kind = DEF_ENUM;
  188.     scan(TOK_IDENT, &tok);
  189.     defp->def_name = tok.str;
  190.     scan(TOK_LBRACE, &tok);
  191.     tailp = &defp->def.en.vals;
  192.     do {
  193.         scan(TOK_IDENT, &tok);
  194.         elist = ALLOC(enumval_list);
  195.         elist->name = tok.str;
  196.         elist->assignment = NULL;
  197.         scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
  198.         if (tok.kind == TOK_EQUAL) {
  199.             scan_num(&tok);
  200.             elist->assignment = tok.str;
  201.             scan2(TOK_COMMA, TOK_RBRACE, &tok);
  202.         }
  203.         *tailp = elist;
  204.         tailp = &elist->next;
  205.     } while (tok.kind != TOK_RBRACE);
  206.     *tailp = NULL;
  207. }
  208.  
  209. static
  210. def_const(defp)
  211.     definition *defp;
  212. {
  213.     token tok;
  214.  
  215.     defp->def_kind = DEF_CONST;
  216.     scan(TOK_IDENT, &tok);
  217.     defp->def_name = tok.str;
  218.     scan(TOK_EQUAL, &tok);
  219.     scan2(TOK_IDENT, TOK_STRCONST, &tok);
  220.     defp->def.co = tok.str;
  221. }
  222.  
  223. static
  224. def_union(defp)
  225.     definition *defp;
  226. {
  227.     token tok;
  228.     declaration dec;
  229.     case_list *cases;
  230.     case_list **tailp;
  231.  
  232.     defp->def_kind = DEF_UNION;
  233.     scan(TOK_IDENT, &tok);
  234.     defp->def_name = tok.str;
  235.     scan(TOK_SWITCH, &tok);
  236.     scan(TOK_LPAREN, &tok);
  237.     get_declaration(&dec, DEF_UNION);
  238.     defp->def.un.enum_decl = dec;
  239.     tailp = &defp->def.un.cases;
  240.     scan(TOK_RPAREN, &tok);
  241.     scan(TOK_LBRACE, &tok);
  242.     scan(TOK_CASE, &tok);
  243.     while (tok.kind == TOK_CASE) {
  244.         scan(TOK_IDENT, &tok);
  245.         cases = ALLOC(case_list);
  246.         cases->case_name = tok.str;
  247.         scan(TOK_COLON, &tok);
  248.         get_declaration(&dec, DEF_UNION);
  249.         cases->case_decl = dec;
  250.         *tailp = cases;
  251.         tailp = &cases->next;
  252.         scan(TOK_SEMICOLON, &tok);
  253.         scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
  254.     }
  255.     *tailp = NULL;
  256.     if (tok.kind == TOK_DEFAULT) {
  257.         scan(TOK_COLON, &tok);
  258.         get_declaration(&dec, DEF_UNION);
  259.         defp->def.un.default_decl = ALLOC(declaration);
  260.         *defp->def.un.default_decl = dec;
  261.         scan(TOK_SEMICOLON, &tok);
  262.         scan(TOK_RBRACE, &tok);
  263.     } else {
  264.         defp->def.un.default_decl = NULL;
  265.     }
  266. }
  267.  
  268.  
  269. static
  270. def_typedef(defp)
  271.     definition *defp;
  272. {
  273.     declaration dec;
  274.  
  275.     defp->def_kind = DEF_TYPEDEF;
  276.     get_declaration(&dec, DEF_TYPEDEF);
  277.     defp->def_name = dec.name;
  278.     defp->def.ty.old_prefix = dec.prefix;
  279.     defp->def.ty.old_type = dec.type;
  280.     defp->def.ty.rel = dec.rel;
  281.     defp->def.ty.array_max = dec.array_max;
  282. }
  283.  
  284.  
  285. static
  286. get_declaration(dec, dkind)
  287.     declaration *dec;
  288.     defkind dkind;
  289. {
  290.     token tok;
  291.  
  292.     get_type(&dec->prefix, &dec->type, dkind);
  293.     dec->rel = REL_ALIAS;
  294.     if (streq(dec->type, "void")) {
  295.         return;
  296.     }
  297.     scan2(TOK_STAR, TOK_IDENT, &tok);
  298.     if (tok.kind == TOK_STAR) {
  299.         dec->rel = REL_POINTER;
  300.         scan(TOK_IDENT, &tok);
  301.     }
  302.     dec->name = tok.str;
  303.     if (peekscan(TOK_LBRACKET, &tok)) {
  304.         if (dec->rel == REL_POINTER) {
  305.             error("no array-of-pointer declarations -- use typedef");
  306.         }
  307.         dec->rel = REL_VECTOR;
  308.         scan_num(&tok);
  309.         dec->array_max = tok.str;
  310.         scan(TOK_RBRACKET, &tok);
  311.     } else if (peekscan(TOK_LANGLE, &tok)) {
  312.         if (dec->rel == REL_POINTER) {
  313.             error("no array-of-pointer declarations -- use typedef");
  314.         }
  315.         dec->rel = REL_ARRAY;
  316.         if (peekscan(TOK_RANGLE, &tok)) {
  317.             dec->array_max = "~0";    /* unspecified size, use max */
  318.         } else {
  319.             scan_num(&tok);
  320.             dec->array_max = tok.str;
  321.             scan(TOK_RANGLE, &tok);
  322.         }
  323.     }
  324.     if (streq(dec->type, "opaque")) {
  325.         if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
  326.             error("array declaration expected");
  327.         }
  328.     } else if (streq(dec->type, "string")) {
  329.         if (dec->rel != REL_ARRAY) {
  330.             error("variable-length array declaration expected");
  331.         }
  332.     }
  333. }
  334.  
  335.  
  336. static
  337. get_type(prefixp, typep, dkind)
  338.     char **prefixp;
  339.     char **typep;
  340.     defkind dkind;
  341. {
  342.     token tok;
  343.  
  344.     *prefixp = NULL;
  345.     get_token(&tok);
  346.     switch (tok.kind) {
  347.     case TOK_IDENT:
  348.         *typep = tok.str;
  349.         break;
  350.     case TOK_STRUCT:
  351.     case TOK_ENUM:
  352.     case TOK_UNION:
  353.         *prefixp = tok.str;
  354.         scan(TOK_IDENT, &tok);
  355.         *typep = tok.str;
  356.         break;
  357.     case TOK_UNSIGNED:
  358.         unsigned_dec(typep);
  359.         break;
  360.     case TOK_SHORT:
  361.         *typep = "short";
  362.         (void) peekscan(TOK_INT, &tok);
  363.         break;
  364.     case TOK_LONG:
  365.         *typep = "long";
  366.         (void) peekscan(TOK_INT, &tok);
  367.         break;
  368.     case TOK_VOID:
  369.         if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
  370.             error("voids allowed only inside union and program definitions");
  371.         }
  372.         *typep = tok.str;
  373.         break;
  374.     case TOK_STRING:
  375.     case TOK_OPAQUE:
  376.     case TOK_CHAR:
  377.     case TOK_INT:
  378.     case TOK_FLOAT:
  379.     case TOK_DOUBLE:
  380.     case TOK_BOOL:
  381.         *typep = tok.str;
  382.         break;
  383.     default:
  384.         error("expected type specifier");
  385.     }
  386. }
  387.  
  388.  
  389. static
  390. unsigned_dec(typep)
  391.     char **typep;
  392. {
  393.     token tok;
  394.  
  395.     peek(&tok);
  396.     switch (tok.kind) {
  397.     case TOK_CHAR:
  398.         get_token(&tok);
  399.         *typep = "u_char";
  400.         break;
  401.     case TOK_SHORT:
  402.         get_token(&tok);
  403.         *typep = "u_short";
  404.         (void) peekscan(TOK_INT, &tok);
  405.         break;
  406.     case TOK_LONG:
  407.         get_token(&tok);
  408.         *typep = "u_long";
  409.         (void) peekscan(TOK_INT, &tok);
  410.         break;
  411.     case TOK_INT:
  412.         get_token(&tok);
  413.         *typep = "u_int";
  414.         break;
  415.     default:
  416.         *typep = "u_int";
  417.         break;
  418.     }
  419. }
  420.